# 1 "head.S"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "head.S"
# 24 "head.S"
.text

# 1 "linkage.h" 1



# 1 "config.h" 1
# 5 "linkage.h" 2
# 27 "head.S" 2
# 1 "segment.h" 1
# 28 "head.S" 2

 .globl startup_32

startup_32:
 cld
 cli
 movl $(0x18),%eax
 movl %eax,%ds
 movl %eax,%es
 movl %eax,%fs
 movl %eax,%gs

 lss stack_start,%esp
 xorl %eax,%eax
1: incl %eax # check that A20 really IS enabled
 movl %eax,0x000000 # loop forever if it isn't
 cmpl %eax,0x100000
 je 1b






 pushl $0
 popfl



 xorl %eax,%eax
 movl $ _edata,%edi
 movl $ _end,%ecx
 subl %edi,%ecx
 cld
 rep
 stosb



 subl $16,%esp # place for structure on the stack
 movl %esp,%eax
 pushl %esi # real mode pointer as second arg
 pushl %eax # address of structure as first arg
 call decompress_kernel
 orl %eax,%eax
 jnz 3f
 popl %esi # discard address
 popl %esi # real mode pointer
 xorl %ebx,%ebx
 ljmp $(0x10), $0x100000







3:
 movl $move_routine_start,%esi
 movl $0x1000,%edi
 movl $move_routine_end,%ecx
 subl %esi,%ecx
 addl $3,%ecx
 shrl $2,%ecx
 cld
 rep
 movsl

 popl %esi # discard the address
 popl %ebx # real mode pointer
 popl %esi # low_buffer_start
 popl %ecx # lcount
 popl %edx # high_buffer_start
 popl %eax # hcount
 movl $0x100000,%edi
 cli # make sure we don't get interrupted
 ljmp $(0x10), $0x1000 # and jump to the move routine





move_routine_start:
 movl %ecx,%ebp
 shrl $2,%ecx
 rep
 movsl
 movl %ebp,%ecx
 andl $3,%ecx
 rep
 movsb
 movl %edx,%esi
 movl %eax,%ecx # NOTE: rep movsb won't move if %ecx == 0
 addl $3,%ecx
 shrl $2,%ecx
 rep
 movsl
 movl %ebx,%esi # Restore setup pointer
 xorl %ebx,%ebx
 ljmp $(0x10), $0x100000
move_routine_end:
